using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Xml.Serialization;

namespace Nizm0.QOT.Library.Objects
{
    [Serializable]
    public class Table :Objects.ISettingsObjects, IXmlSerializable
    {
        public static int ObjectCount = 0;
        private int _id;
        private string _name;
        private string _schema = "dbo";
        private bool _exists = false;
        private DateTime _createdate;
        private int _count;
        private DateTime _mindate = DateTime.MinValue;
        private DateTime _maxdate = DateTime.MaxValue;
        private DateTime _refreshdate;
        private bool _wasrefreshed = false;
        private int _daysofdata;
        private DateTime _lastdataquerydate;
        private List<string> _columns = new List<string>();

        private int _treelewel = 3;
        private bool _checked = false;
        private object _parent;

        private string _columnNameForData = "TextData";
        private string _columnNameForDuration = "Duration";
        private string _columnNameForReads = "Reads";
        private string _columnNameForStartTime = "StartTime";

        public delegate void DelegateCheckedChanged(Table sender);
        public event DelegateCheckedChanged CheckedChanged;

        #region Propertiess

        [CategoryAttribute("Misc"), ReadOnlyAttribute(true)]
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }
        /*
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        */
        [CategoryAttribute("Misc"), ReadOnlyAttribute(true)]
        public string Schema
        {
            get { return _schema; }
            set { _schema = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public bool ExistInDB
        {
            get { return _exists; }
            set { _exists = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public DateTime CreateDate
        {
            get { return _createdate; }
            set { _createdate = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public int Count
        {
            get { return _count; }
            set { _count = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public DateTime MinDate
        {
            get { return _mindate; }
            set { _mindate = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public DateTime MaxDate
        {
            get { return _maxdate; }
            set { _maxdate = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public DateTime RefreshDate
        {
            get { return _refreshdate; }
            set { _refreshdate = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public bool WasRefreshed
        {
            get { return _wasrefreshed; }
            set { _wasrefreshed = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public int DaysOfData
        {
            get { return _daysofdata; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public DateTime Lastdataquerydate
        {
            get { return _lastdataquerydate; }
            set { _lastdataquerydate = value; }
        }
        [CategoryAttribute("Additional Info"), ReadOnlyAttribute(true)]
        public List<string> Columns
        {
            get { return _columns; }
            set { _columns = value; }
        }
        [CategoryAttribute("Misc"), ReadOnlyAttribute(true)]
        public object Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        /*
        public bool Checked
        {
            get { return _checked; }
            set { _checked = value; }
        }
        */
        public string ColumnNameForData
        {
            get { return _columnNameForData; }
            set { _columnNameForData = value; }
        }
        public string ColumnNameForDuration
        {
            get { return _columnNameForDuration; }
            set { _columnNameForDuration = value; }
        }
        public string ColumnNameForReads
        {
            get { return _columnNameForReads; }
            set { _columnNameForReads = value; }
        }
        public string ColumnNameForStartTime
        {
            get { return _columnNameForStartTime; }
            set { _columnNameForStartTime = value; }
        } 
        #endregion

        #region Objects.ISettingsObjects Members

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public int Treelevel
        {
            get
            {
                return _treelewel;
            }
        }

        public bool Checked
        {
            get
            {
                return _checked;
            }
            set
            {
                _checked = value;
                if (CheckedChanged != null)
                    CheckedChanged(this);
            }
        }

        #endregion

        #region Constructors
        public Table(int ID, string Name, DateTime CreateDate, int Count, DateTime MinDate, DateTime MaxDate, DateTime RefreshDate, bool WasRefreshed)
        {
            ObjectCount++;
            this._id = ID;
            this._name = Name;
            this._createdate = CreateDate;
            this._count = Count;
            this._mindate = MinDate;
            this._maxdate = MaxDate;
            this._refreshdate = RefreshDate;
            this._wasrefreshed = WasRefreshed;
        }
        public Table(int ID, string Name, string Schema)
        {
            ObjectCount++;
            this._id = ID;
            this._name = Name;
            this._schema = Schema;
            this._createdate = DateTime.MinValue;
            this._count = 0;
            this._mindate = DateTime.MinValue;
            this._maxdate = DateTime.MaxValue;
            this._refreshdate = DateTime.MinValue;
            this._wasrefreshed = false;
        }
        public Table(string Name)
        {
            ObjectCount++;
            //this._id = ID;
            this._name = Name;
            this._createdate = DateTime.MinValue;
            this._count = 0;
            this._mindate = DateTime.MinValue;
            this._maxdate = DateTime.MaxValue;
            this._refreshdate = DateTime.MinValue;
            this._wasrefreshed = false;
        }
        public Table()
        {
            ObjectCount++;
            //_id = 
            this._name = string.Empty;
            this._createdate = DateTime.MinValue;
            this._count = 0;
            this._mindate = DateTime.MinValue;
            this._maxdate = DateTime.MaxValue;
            this._refreshdate = DateTime.MinValue;
            this._wasrefreshed = false;
        }
        ~Table()
        {
            ObjectCount--;
        }
        #endregion

        public override string ToString()
        {
            return _name;
        }
        #region Methods

        /// <summary>
        /// Check how many days of data in this table
        /// </summary>
        public void CountDaysOfData()
        {
            int years = 0;
            int month = 0;
            int days = 0;
            years = _maxdate.Year - _mindate.Year;
            month = (_maxdate.Month - _mindate.Month) + (12 * years);

            days = _maxdate.Day - _mindate.Day;

            for (int i = _mindate.Month; i < _maxdate.Month; i++)
            {
                days += DateTime.DaysInMonth(_mindate.Year, i);
            }
            for (int i = 0; i < years; i++)
            {
                if (DateTime.IsLeapYear(_mindate.Year + i))
                {
                    days += 366;
                }
                else
                {
                    days += 365;
                }
            }
            _daysofdata = days;
            //_maxdate
        }

        public void Marge(Table table)
        {
            if (_checked || table.Checked)
                _checked = true;
            else
                _checked = false;
        } 
        #endregion

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            _name = reader.GetAttribute("Name");
            _schema = reader.GetAttribute("Schema");
            Boolean.TryParse(reader.GetAttribute("Checked"), out _checked);
            DateTime.TryParse(reader.GetAttribute("CreateDate"), out _createdate);
            Int32.TryParse(reader.GetAttribute("Count"), out _count);
            DateTime.TryParse(reader.GetAttribute("MinDate"), out _mindate);
            DateTime.TryParse(reader.GetAttribute("MaxDate"), out _maxdate);
            DateTime.TryParse(reader.GetAttribute("RefreshDate"), out _refreshdate);
            Boolean.TryParse(reader.GetAttribute("WasRefreshed"), out _wasrefreshed);
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteAttributeString("Name", _name);
            writer.WriteAttributeString("Schema", _schema);
            writer.WriteAttributeString("Checked", _checked.ToString());
            writer.WriteAttributeString("CreateDate", _createdate.ToUniversalTime().ToString());
            writer.WriteAttributeString("Count", _count.ToString());
            writer.WriteAttributeString("MinDate", _mindate.ToUniversalTime().ToString());
            writer.WriteAttributeString("MaxDate", _maxdate.ToUniversalTime().ToString());
            writer.WriteAttributeString("RefreshDate", _refreshdate.ToUniversalTime().ToString());
            writer.WriteAttributeString("WasRefreshed", _wasrefreshed.ToString());
        }
    }
}
